package com.link.base.base.project.service;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.link.base.base.approval.model.Flow;
import com.link.base.base.approval.service.FlowService;
import com.link.base.base.contactinfo.dao.mybatis.mapper.ContactInfoMapper;
import com.link.base.base.message.push.service.PushService;
import com.link.base.base.product.dao.mybatis.mapper.PartsCostMapper;
import com.link.base.base.product.dao.mybatis.mapper.QuotePartsCostMapper;
import com.link.base.base.product.model.PartsCost;
import com.link.base.base.product.model.PcdData;
import com.link.base.base.product.service.ComputeQuotePartsCostService;
import com.link.base.base.product.service.PartsCostService;
import com.link.base.base.product.service.PcdDataService;
import com.link.base.base.product.service.ProdQuoteService;
import com.link.base.base.project.dao.mybatis.mapper.ProjectCarOutputMapper;
import com.link.base.base.project.dao.mybatis.mapper.ProjectMapper;
import com.link.base.base.project.dao.mybatis.mapper.QuoteRoundMapper;
import com.link.base.base.project.model.Project;
import com.link.base.base.project.model.ProjectNode;
import com.link.base.base.project.model.ProjectNodeInfo;
import com.link.base.base.project.model.QuoteRound;
import com.link.base.base.projectmanage.model.CarRegister;
import com.link.base.base.projectmanage.model.TaskInfo;
import com.link.base.base.projectmanage.service.CarRegisterService;
import com.link.base.base.projectmanage.service.TaskInfoService;
import com.link.base.core.basic.util.BigDecimalUtils;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.DateUtil;
import com.link.core.util.LovUtil;
import com.link.core.util.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 项目
 *
 * @author 阳晓琳
 * @date 2020-09-21 16:36:57
 */
@Service
public class ProjectServiceImpl extends BasicServiceImpl<Project> implements ProjectService {

    @Resource
    private ProjectMapper    projectMapper;

    @Resource
    private CarRegisterService carRegisterService;

    @Resource
    private ProjectNodeService projectNodeService;

    @Resource
    private ProjectNodeInfoService projectNodeInfoService;

    @Resource
    private QuoteRoundService quoteRoundService;

    @Resource
    private ComputeQuotePartsCostService computeQuotePartsCostService;

    @Resource
    private FlowService flowService;

    @Resource
    private ProdQuoteService prodQuoteService;

    @Resource
    private TaskInfoService taskInfoService;

    @Resource
    private PushService pushService;

    @Resource
    private ProjectCarOutputService projectCarOutputService;

    @Resource
    private PartsCostService partsCostService;

    @Resource
    private ProjectCarOutputMapper projectCarOutputMapper;
    @Resource
    private PartsCostMapper partsCostMapper;
    @Resource
    private QuoteRoundMapper quoteRoundMapper;
    @Resource
    private ContactInfoMapper contactInfoMapper;

    @Resource
    private QuotePartsCostMapper quotePartsCostMapper;

    @Resource
    private PcdDataService pcdDataService;

    @Override
    public BasicMapper<Project> getBasicMapper() {
        return projectMapper;
    }


    /**
     * 当“项目阶段”为立项阶段，“是否评审”为是时：点击保存后，头字段“项目阶段”变为评审阶段
     * @param entity
     * @throws Exception
     */
    @Override
    public void beforUpsert(Project entity) throws Exception {
        super.beforUpsert(entity);
        //当“项目阶段”为立项阶段（ProjectStage），“是否评审”为是时：点击保存后，头字段“项目阶段”变为评审阶段（ReviewStage）。
        if ("ProjectStage".equals(entity.getProjectStage()) && "Y".equals(entity.getApprFlag())) {
            entity.setProjectStage("ReviewStage");
        } else if ("ProjectStage".equals(entity.getProjectStage()) && "N".equals(entity.getApprFlag())) {
            entity.setProjectStage("ProjectStage");
        }
    }

    /**
     * 当新建项目信息时，根据所选择的车型登记带出的终端主机厂，自动匹配终端主机厂的节点名称
     * 新建项目，子页签插入五条拜访计划
     * @param entity
     * @throws Exception
     */
    @Override
    public void beforInsert(Project entity) throws Exception {
        super.beforInsert(entity);
         //当新建项目信息时，根据所选择的车型登记带出的终端主机厂，自动匹配终端主机厂的节点名称
         //预生成项目节点信息的表格内容及记录ID。终端主机厂值来源：客户表
         //业务流程：客户表新建是终端主机厂的客户，再项目节点表为该客户维护对应节点
         //车型登记表为对应客户选择终端主机厂，项目信息表为项目选择车型登记号关联带出终端主机厂，
         //点击保存后再节点信息中插入对应节点
        //1.根据当前项目实体的车型登记号，去车型登记表查询对应车型登记，得到终端主机厂id
        CarRegister carReg = new CarRegister();
        carReg.setId(entity.getClueId());
        CarRegister carRegister = carRegisterService.queryById(carReg);
        //2.根据终端主机厂id去项目节点表查询对应节点，结果集为节点序号倒叙查询
        ProjectNode projectNode = new ProjectNode();
        projectNode.setAcctId(carRegister.getAccntId());
        List<ProjectNode> projectNode1 = projectNodeService.queryByEngineeId(projectNode);
        //3.新建项目节点信息表对象
        ProjectNodeInfo projectNodeInfo = new ProjectNodeInfo();
        //4.将查询到的节点名称插入项目节点信息表节点名称
        for (ProjectNode projectNode2 :projectNode1) {
            projectNodeInfo.setId(keyGenerateService.keyGenerate());
            projectNodeInfo.setProjectId(entity.getId());
            projectNodeInfo.setProjectNode(projectNode2.getNodeName());
            projectNodeInfoService.insert(projectNodeInfo);
        }

        //新建一个项目，自动添加五条阶段拜访计划到拜访计划表
        //1.新建拜访计划实体，存入当前项目id
        TaskInfo taskInfo = new TaskInfo();
        taskInfo.setProjectHeadId(entity.getId());
        String[] stage = {"SynchronizedDesign","RFQObtained","QuoteStage","CompetitorAnalysis","PointStage"};
        //2.for循环，插入五条阶段拜访
        for (int i = 0; i < 5; i++) {
            //插入五条不同的拜访记录，头ID不同
            taskInfo.setId(keyGenerateService.keyGenerate());
            taskInfo.setCurrentStage(stage[i]);
            taskInfoService.insert(taskInfo);
        }
    }


    /**
     * 编辑项目客户后，更新节点信息
     * 编辑车型登记后，重新拼接项目经理
     * @param entity
     * @throws Exception
     */
    @Override
    public void beforUpdate(Project entity) throws Exception {
        super.beforUpdate(entity);
        /**
         *编辑项目后，更新节点信息
         */
        //1.根据当前项目实体的车型登记号，去车型登记表查询对应车型登记，得到终端主机厂id
        CarRegister carReg = new CarRegister();
        carReg.setId(entity.getClueId());
        CarRegister carRegister = carRegisterService.queryById(carReg);
        if (carRegister != null) {
            //2.根据终端主机厂id去项目节点表查询对应节点，结果集为节点序号倒叙查询
            ProjectNode projectNode = new ProjectNode();
            projectNode.setAcctId(carRegister.getAccntId());
            List<ProjectNode> projectNode1 = projectNodeService.queryByEngineeId(projectNode);
            //3.新建项目节点信息表对象
            ProjectNodeInfo projectNodeInfo = new ProjectNodeInfo();
            //4.将查询到的节点名称插入项目节点信息表节点名称
            for (ProjectNode projectNode2 :projectNode1) {
                projectNodeInfo.setId(keyGenerateService.keyGenerate());
                projectNodeInfo.setProjectId(entity.getId());
                projectNodeInfo.setProjectNode(projectNode2.getNodeName());
                projectNodeInfoService.update(projectNodeInfo);
            }
        } else {
            //未找到选择的车型登记信息  您当前项目所选车型登记号不存在，请重新选择！
            throw new ServiceException("IYUPROJECT-003");
        }


        //编辑车型登记后，重新拼接业务经理 (直接从客户拿mvg过来，车型业务经理mvg已取消)
        //1.根据entity选择的车型登记号，去车型登记表查询记录，关联车型业务经理中间表
//        CarRegister car = new CarRegister();
//        car.setId(entity.getClueId());
//        List<CarRegister> carRegisters = carRegisterService.querySalemanById(car);
        //2.将查询出来的记录遍历，拼接业务经理，set到busmanagename
//        if (carRegisters != null) {
//            String saleMan = "";
//            for (CarRegister carRegister1 : carRegisters) {
//                if (saleMan.equals("")) {
//                    saleMan = carRegister1.getBusManagerName();
//                } else {
//                    saleMan = saleMan + "/" + carRegister1.getBusManagerName();
//                }
//            }
//            entity.setBusManageName(saleMan);
//        }
    }

    /**
     * 报价审批
     * @param entity
     * @throws Exception
     */
    @Override
    public void projectQuoteSubmit(Project entity) throws Exception {

        /*ComputeQuotePartsCost computeQuotePartsCost = new ComputeQuotePartsCost();
        computeQuotePartsCost.setProjectId(entity.getId());
        List<ComputeQuotePartsCost> computeQuotePartsCostList = computeQuotePartsCostService.queryByExamplePage(computeQuotePartsCost);
        if (CollectionUtils.isEmpty(computeQuotePartsCostList)) {
            throw new RuntimeException("最终报价不能为空!");
        }*/

        // 调整为，pcd不为空
        PcdData pcdData = new PcdData();
        pcdData.setProjectId(entity.getId());
        List<PcdData> pcdDataList = pcdDataService.queryByExamplePage(pcdData);
        if (CollectionUtils.isEmpty(pcdDataList)) {
            throw new RuntimeException("Pcd表数据不能为空!");
        }
        //
        //1.点击【审批】时校验最新轮次报价列表信息中字段“客户价格”是否存在。提示“需将最终轮次的客户价格补全后，才可进行报价审批”
        //1.1根据项目id，查询最新一轮报价
        /*QuoteRound quoteRound1 = new QuoteRound();
        quoteRound1.setProjectHeadId(entity.getId());
        List<QuoteRound> quoteRoundList = quoteRoundService.queryByExamplePage(quoteRound1);
        if (quoteRoundList == null || quoteRoundList.size() == 0 ) {
            throw new ServiceException("IYUPROJECT-004");
        }
        QuoteRound quoteRoundEntity = quoteRoundList.get(0);*/
        //1.2根据最后更新时间倒叙查询，取list的第一条数据，校验查询结果的客户价格是否为空，为空则抛出
        /*if (quoteRoundEntity.getCustPrice() == null) {
            throw new ServiceException("IYUPROJECT-001");
        }*/

        /**
         * 以19%为边界的零件类型为：氛围灯、立柱、前后门槛、尾门+所护板、后舱后侧尾、发动机舱塑料件、座椅背板、中央通道、顶灯、出风口、门板、冲压小件、焊接总成。当零件类型有其中的值时，需按照19%的边界控制审批。
         * 以25%为边界的零件类型为：无线充电、铜排、换挡、手刹、螺母板、套同类。当零件类型有其中的值时，需按照25%的边界控制审批
         *毛利率是否大于19,25
         */
        //2.创建审批流
        //2.1根据当前项目头ID，查询零件类型，验证零件类型
        Project record = this.queryById(entity);
        // 设置最终报价信息
        // record.setComputeQuotePartsCostList(computeQuotePartsCostList);
        // 设置pcd数据
        record.setPcdDataList(pcdDataList);
        /*QuotePartsCost quotePartsCostParam = new QuotePartsCost();
        quotePartsCostParam.setProjectId(entity.getId());
        List<QuotePartsCost> quotePartsCostList = quotePartsCostMapper.queryByProjectId(quotePartsCostParam);
        record.setQuotePartsCostList(quotePartsCostList);*/


        //根据报价轮次查询所有总成报价
        /*ProdQuote queryProdOne = new ProdQuote();
        queryProdOne.setQuoteRoundId(quoteRoundEntity.getId());
        queryProdOne.setAttr1("assemblyParts");
        queryProdOne.setPageFlag(false);
        List<ProdQuote> prodQuoteList = prodQuoteService.queryByExamplePage(queryProdOne);
        for (ProdQuote prodQuote : prodQuoteList) {
            ProdQuote queryPartOne = new ProdQuote();
            queryPartOne.setQuoteRoundId(prodQuote.getQuoteRoundId());
            queryPartOne.setcRMAssemblysId(prodQuote.getcRMPartId());
            queryPartOne.setPageFlag(false);
            List<ProdQuote> partsList = prodQuoteService.queryByExamplePage(queryPartOne);
            prodQuote.setProdQuoteList(partsList);
        }

        quoteRoundEntity.setProdQuoteList(prodQuoteList);

        List<QuoteRound> quoteRounds = new ArrayList<>();
        quoteRounds.add(quoteRoundEntity);
        record.setQuoteRoundList(quoteRounds);*/
        //新建集合存放25类型的零件
        /*List<String> isTwenty = new ArrayList<>();
        isTwenty.add("NutSet");
        isTwenty.add("NutPlate");
        isTwenty.add("ManualBrake");
        isTwenty.add("ShiftGears");
        isTwenty.add("CopperBar");
        isTwenty.add("WirelessCharger");
        boolean isTwen = false;*/

        //遍历查询出来的零件类型list，判断每一个零件类型是否存在于istwenty数组,存在则创建
        //同一个项目，很多个零件 遍历每一个零件，判断数组istwenty 25类型的零件 中是否包含本项目零件   零件中只要含有25类零件的走25审批流
        //for (Project project1 : project) {
        /*String partName = record.getPartsTypeName();*/
        //如果此列表包含partname,则返回true
        /*isTwen = isTwenty.contains(partName);*/
        //25类零件 istwen 为真  本项目零件中包含25类型零件
        /*if (isTwen) {
            //0.25 大于 本项目利率    项目报价董事长审批
            if (new BigDecimal(0.25).compareTo(entity.getAvgGrossing()) == 1) {
                //根据零件类型所属边界类别创建审批流
                String approvalType = "ProjectQuoteSubmit";
                String approvalDetail = JSON.toJSONString(record);
                //创建审批流程
                flowService.createFlow(entity.getId(), approvalType, null,
                        entity.getProjectCode() + "-" + entity.getAcctName(),entity.getId(), approvalDetail);
                //点击审批按钮，审批状态由新建-->审批中
                entity.setApprovalStatus("InApproval");
                projectMapper.update(entity);
                //break;
            } else {
                //0.25 小于 项目利率  项目报价科长审批
                //根据零件类型所属边界类别创建审批流
                String approvalType = "ProjectQuoteAppro";
                ObjectMapper mapper = new ObjectMapper();
                String approvalDetail = JSON.toJSONString(record);
                //String approvalDetail = mapper.writeValueAsString(record);
                //创建审批流程
                flowService.createFlow(entity.getId(), approvalType, null,
                        entity.getProjectCode() + "-" + entity.getAcctName(),entity.getId(), approvalDetail);
                //点击审批按钮，审批状态由新建-->审批中
                entity.setApprovalStatus("InApproval");
                projectMapper.update(entity);
                //break;
            }

        }
        //}
        if (!isTwen) {
            //0.19 大于 项目利率 项目报价董事长审批
            if (new BigDecimal(0.19).compareTo(entity.getAvgGrossing()) > 0 ) {
                //2.2根据零件类型所属边界类别创建审批流
                String approvalType = "ProjectQuoteSubmit";
                ObjectMapper mapper = new ObjectMapper();
                //String approvalDetail = mapper.writeValueAsString(entity);
                String approvalDetail = JSON.toJSONString(record);
                //创建审批流程
                flowService.createFlow(entity.getId(), approvalType, null,
                        entity.getProjectCode() + "-" + entity.getAcctName(),entity.getId(), approvalDetail);
                //点击审批按钮，审批状态由新建-->审批中
                entity.setApprovalStatus("InApproval");
                projectMapper.update(entity);
            } else {
                //0.19 小于项目利率  项目报价科长审批
                //2.2根据零件类型所属边界类别创建审批流
                String approvalType = "ProjectQuoteAppro";
                ObjectMapper mapper = new ObjectMapper();
                String approvalDetail = JSON.toJSONString(record);
                //String approvalDetail = mapper.writeValueAsString(entity);
                //创建审批流程
                flowService.createFlow(entity.getId(), approvalType, null,
                        entity.getProjectCode() + "-" + entity.getAcctName(),entity.getId(), approvalDetail);
                //点击审批按钮，审批状态由新建-->审批中
                entity.setApprovalStatus("InApproval");
                projectMapper.update(entity);
            }

        }*/


        String approvalType = "ProjectQuoteAppro";
        ObjectMapper mapper = new ObjectMapper();
        String approvalDetail = JSON.toJSONString(record);
        //String approvalDetail = mapper.writeValueAsString(entity);
        //创建审批流程
        flowService.createFlow(entity.getId(), approvalType, null,
                entity.getProjectCode() + "-" + entity.getAcctName(),entity.getId(), approvalDetail);
        //点击审批按钮，审批状态由新建-->审批中
        entity.setApprovalStatus("InApproval");
        projectMapper.update(entity);
    }

    /**
     * 报价提交
     * @param entity
     * @throws Exception
     */
    @Override
    public void submitInfo(Project entity) throws Exception {
        // 1、年产量不能为空  projectCarOutputMapper
        Integer count1 = projectCarOutputMapper.countByProjectId(entity.getId());
        if (count1 <= 0) {
            throw new RuntimeException("请维护年产量信息!");
        }
        // 2、成本汇总不能为空  partsCostMappe
        Integer count2 = partsCostMapper.countByProjectId(entity.getId());
        if (count2 <= 0) {
            throw new RuntimeException("请维护成本汇总!");
        }
        // 3、对外报价不能为空  quoteRoundMapper
        /*Integer count3 = quoteRoundMapper.countByProjectId(entity.getId());
        if(count3 <= 0) {
            throw new RuntimeException("请维护对外报价!");
        }*/
        // 4、项目联系人不能为空  contactInfoMapper
        Integer count4 = contactInfoMapper.countByProjectId(entity.getId());
        if (count4 <= 0) {
            throw new RuntimeException("请维护项目联系人!");
        }

        Project project = projectMapper.queryById(entity);
        if (null == project || StringUtils.isNull(project.getApprResult())) {
            throw new RuntimeException("项目信息丢失或评审结果为空!");
        }
        // 同意承接: AgreeUndertake  生成承接单
        /*if ("AgreeUndertake".equals(project.getApprResult())) {

        }*/
        // 拒绝承接：RefuseUndertake  生成失标项目
       /* if ("RefuseUndertake".equals(project.getApprResult())) {

        }*/

    }

    /**
     * 报价审批结果处理
     * @param flow
     * @param arg1
     * @param arg2
     * @param arg3
     * @param arg4
     * @param arg5
     * @throws Exception
     */
    @Override
    public void apprProjectQuote(Flow flow, String arg1, String arg2, String arg3, String arg4, String arg5) throws Exception {
        Long projectId = flow.getFlowObjId();
        Project project = new Project();
        project.setId(projectId);
        project.setApprovalStatus(arg1);
        projectMapper.updateStatus(project);
    }

    /**
     * 进入项目详情页，计算字段值
     * @param entity
     * @return
     * @throws Exception
     */
    @Override
    public Project queryById(Project entity) throws Exception {
        //点击项目ID进入详情页，计算各项价格
        //项目成本总价：该项目最新轮次所有总成件的“工厂成本（未含模摊）”相加之和。“工厂成本（未含模摊）”的来源为：零件成本表。
        //根据项目ID去报价轮次查最新轮次报价

        //根据创建时间倒叙排列，取第一条报价轮次ID
        Project project = super.queryById(entity);
        //查询项目ID查询报价轮次
        QuoteRound quoteRound = new QuoteRound();
        quoteRound.setProjectHeadId(entity.getId());
        List<QuoteRound> quoteRounds = quoteRoundService.queryByExamplePage(quoteRound);
        if (quoteRounds.size() > 0) {
            //生成报价轮次的项目
            QuoteRound record = quoteRounds.get(0);
            BigDecimal zero = new BigDecimal(0);

            //模检夹总和
            project.setMouldCostSum(record.getMouldCostSum());

            //项目成本总价 该项目所有总成件的“工厂成本（未含模摊）”相加之和。“工厂成本（未含模摊）”的来源为：零件成本表。
            project.setTotalProjectCost(record.getFactoryCost());
            //成本均车总价 所有零件成本均车价之和。单一零件成本均车价=该零件的工厂成本（未含模摊）*装车比*数量 。“工厂成本（未含模摊）、装车比、数量”的值来源为：零件成本表。
            project.setTotalCarAmount(record.getPartAvgCarCost());
            //项目报价总金额 当最新轮次的报价信息中有字段 “客户价格”的值时，此处呈现“客户价格”的值,否则此处呈现“商务价格”的值
            BigDecimal businessPrice = BigDecimalUtils.changeNullToZero(record.getBusinessPrice());
            BigDecimal custPrice = BigDecimalUtils.changeNullToZero(record.getCustPrice());
            if (record.getCustPrice() == null) {
                project.setTotalQuotationAmount(businessPrice);
            } else {
                project.setTotalQuotationAmount(custPrice);
            }
            //项目报价均车值 当最新轮次的报价信息中有字段 “客户价格均车价”的值时，此处呈现“客户价格均车价”的值,否则此处呈现“均车价”的值
            BigDecimal avgCarPrice = BigDecimalUtils.changeNullToZero(record.getAvgCarPrice());
            BigDecimal custAvgCarPrice = BigDecimalUtils.changeNullToZero(record.getCustAvgCarPrice());
            if (record.getCustAvgCarPrice() == null) {
                project.setAvgQuotaCost(avgCarPrice);
            } else {
                project.setAvgQuotaCost(custAvgCarPrice);
            }
            //项目毛利率 （项目报价总金额-项目成本总价）/项目报价总金额。
            if (project.getTotalQuotationAmount() == null || (zero.compareTo(project.getTotalQuotationAmount()) == 0)) {
                project.setGrossing(zero);
            } else {
                project.setGrossing((project.getTotalQuotationAmount().subtract(project.getTotalProjectCost())).divide(
                        project.getTotalQuotationAmount(),7,BigDecimal.ROUND_HALF_UP));
            }
            //项目均车毛利率 （项目报价均车值-项目成本均车总价）/项目报价均车值。
            BigDecimal avgQuotaCost = project.getAvgQuotaCost();
            if (avgQuotaCost == null || zero.compareTo(avgQuotaCost) == 0) {
                project.setAvgGrossing(zero);
            } else {
                project.setAvgGrossing((avgQuotaCost.subtract(project.getTotalCarAmount())).divide(
                        avgQuotaCost,7,BigDecimal.ROUND_HALF_UP));
            }
        } else {
            //去成本表取出总价
            PartsCost queryPartsCost = new PartsCost();
            queryPartsCost.setProjectId(entity.getId());
            queryPartsCost.setAttr1("assemblyParts");
            List<PartsCost> partsCostList = partsCostService.queryAll(queryPartsCost);
            BigDecimal totalFactoryCost = BigDecimal.ZERO;
            BigDecimal totalAvgCarCost = BigDecimal.ZERO;
            for (PartsCost partsCost : partsCostList) {

                /** 对象变更
                BigDecimal factoryCost = BigDecimalUtils.changeNullToZero(partsCost.getFactoryCost());
                BigDecimal avgCarCost = BigDecimalUtils.changeNullToZero(partsCost.getAvgVehicleCost());
                totalAvgCarCost = totalAvgCarCost.add(avgCarCost);
                totalFactoryCost = totalFactoryCost.add(factoryCost);
                 **/
            }
            project.setTotalProjectCost(totalFactoryCost);
            project.setTotalCarAmount(totalAvgCarCost);
        }
        return project;
    }

    /**
     * 功能背景：当商务人员进行拜访计划的制定时，会填写字段“预计开始时间”。此时系统会根据预计开始时间的值进行提醒设置。
     * 功能说明：当商务人员成功保存拜访计划后，实际开始时间没有值时，根据字段“预计开始时间”的值提前七天做预警提示。
     * @throws Exception
     */
    @Override
    public void projectVisit() throws Exception {
        //1.查询所有项目对应的拜访计划，判断每个拜访计划是否有预计开始时间
        Project entity = new Project();
        List<Project> projects = projectMapper.queryByExamplePage(entity);
        TaskInfo taskInfo = new TaskInfo();
        for (Project project : projects) {
            taskInfo.setProjectHeadId(project.getId());
            List<TaskInfo> taskInfos = taskInfoService.queryByExamplePage(taskInfo);
            for (TaskInfo taskInfo1 : taskInfos) {
                if (taskInfo1.getEstStartDate() != null) {
                    //获取当前系统时间
                    Date date = new Date();
                    //简单日期格式
//                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    //将taskInfo1.getEstStartDate() 的字符串String解析成data
                    Date parseEstStartDate = DateUtil.DATETIME_FORMATTER.parse(taskInfo1.getEstStartDate());
//                    Date date1 = df.parse(taskInfo1.getEstStartDate());
                    Date estStartDate = new Date(parseEstStartDate.getTime() - 7 * 24 * 60 * 60 * 1000);
                    //当前阶段 值列表源码转换
                    String est = LovUtil.getLovName("LNK_PRESENT_STAGE", taskInfo1.getCurrentStage());
                    String message = "您的" + project.getProjectCode() + "项目于" + taskInfo1.getEstStartDate()
                            + "有阶段为" + est + "的拜访计划需要进行，请及时处理";
                    //判断今天是否在预计开始日期前第七天 之后，对本项目的每一个拜访计划做提醒
                    if (taskInfo1.getActStartDate() == null && estStartDate.before(date)) {
                        sendPushNotice(taskInfo1.getId(),project.getId(),message,taskInfo1.getCreatedBy());
                    }
                } else {
                    break;
                }
            }
        }
    }

    @Override
    public List<Project> projectYearTotalReportPage(Project entity) throws Exception {
        return projectMapper.projectYearTotalReportPage(entity);
    }

    /**
     * 发送系统消息
     *
     * @author NingLanhao
     * @param businessId   预警对象数据的row_id，如消费者id、拜访id
     * @param alertId      头ID
     * @param message 预警消息
     * @param userId       发送对象
     * @return void
     * @date 2019-10-09 14:14
     */
    private void sendPushNotice(Long businessId, Long alertId, String message, Long userId) throws Exception {
        // 发送消息 预警的系统消息里objectId保存预警记录id
        pushService.sampleMessageForModule(message, userId, businessId, "ProjectVisit");
    }

    /**
     * 项目客户层级报表
     * @param entity
     * @return
     * @throws Exception
     */
    @Override
    public List<Project> projectAccountReport(Project entity) throws Exception {
        //根据项目ID，查询项目客户及终端主机场
        Project project = projectMapper.queryById(entity);
        if (project == null) {
            //查询项目头出错，请联系管理员！
            throw new ServiceException("IYUPROJECT-014");
        }
        List<Project> resultList = new ArrayList<>();
        //先校验该项目的字段终端主机厂和客户名称一致，此时矩阵关系图为两层，第一层为客户名称，第二层为一彬电子。
        //若该项目的字段终端主机厂和客户名称不一致，此时矩阵关系图为三层，第一层为终端主机厂，第二层为客户名称，第三层为一彬电子
        Project acct = new Project();
        Project child = new Project();
        if (project.getAcctId().equals(project.getEngineeId())) {
            //客户与终端主机厂一至  外层是客户，内层赋值一彬电子
            acct.setName(project.getAcctName());
            child.setName("一彬电子");
            List<Project> childrenList = new ArrayList<>();
            childrenList.add(child);
            acct.setChildren(childrenList);
            resultList.add(acct);
        } else {
            //客户与终端主机厂不一致 外层是主机厂，内层客户，最内层一彬电子
            Project enginee = new Project();
            List<Project> enginChildList = new ArrayList<>();
            List<Project> acctChildList = new ArrayList<>();
            enginee.setName(project.getMainEngine());
            acct.setName(project.getAcctName());
            child.setName("一彬电子");
            acctChildList.add(child);
            acct.setChildren(acctChildList);
            enginChildList.add(acct);
            enginee.setChildren(enginChildList);
            resultList.add(enginee);
        }
        return resultList;
    }

    /**
     * 20210426 逻辑修改 零件类型mvg-->picklist 取消列表页零件名称拼接
     * 查询项目列表时，查询各项目零件，拼接零件名称
     * @param entity
     * @return
     * @throws Exception
     */
//    @Override
//    public List<Project> queryByExamplePage(Project entity) throws Exception {
//        super.queryByExamplePage(entity);
//        //查询所有项目
//        List<Project> projects = projectMapper.queryByExamplePage(entity);
//        if (projects.size() > 0) {
//            for (Project project : projects) {
//                //去中间表查询所有项目对应零件记录，同时带出零件名称
//                List<Project> projects1 = projectMapper.queryByProId(project);
//                if (projects1.size() > 0) {
//                    //遍历查询出的零件名称，拼接在attr1
//                    String attr1 = "";
//                    for (Project project2 : projects1) {
//                        if (attr1.equals("")) {
//                            attr1 = attr1 + project2.getPartsTypeName();
//                        } else {
//                            attr1 = attr1 + "，" + project2.getPartsTypeName();
//                        }
//                    }
//                    project.setAttr1(attr1);
//                } else {
//                    continue;
//                }
//            }
//            return projects;
//        } else {
//            return projectMapper.queryByExamplePage(entity);
//        }
//    }
}
